#include "Test_Timer.h"

#include <QtTest/QtTest>

#include "Timer.h"

void Test_Timer::test_temporize()
{
    /// Verificamos que el temporizador
    /// sea capaz de correr mas de un ciclo.
    // Numero de ciclos transcurridos.
    int temporized = 0;

    // Creamos un timer para aumentar el
    // numero de ciclos cada 250 ms.
    Timer t1([&]()
    {
        // Aumentamos el numero de ciclos.
        temporized++;

        // En intervalos de 250 ms.
        // NO singleShot.
    }, Timer::Interval(250), false);

    // Iniciamos el temporizador.
    t1.start();

    // Esperamos a que terminen dos ciclos (250 * 2).
    // 50 ms mas para asegurar que el temporizador
    // no se detuvo a medio ciclo.
    std::this_thread::sleep_for(Timer::Interval(550));

    // Detenemos el temporizador.
    t1.stop();

    // Verificamos que se corrieron dos ciclos.
    QCOMPARE(temporized, 2);
}

void Test_Timer::test_singleShot()
{
    /// Verificamos que el temporizador
    /// sea capaz de correr un solo cilco.
    // Numero de ciclos transcurridos.
    int temporized = 0;

    // Creamos un timer para aumentar el
    // numero de ciclos cada 250 ms.
    Timer t1([&]()
    {
        // Aumentamos el numero de ciclos.
        temporized++;

        // En intervalos de 250 ms.
        // SingleShot.
    }, Timer::Interval(250), true);

    // Iniciamos el temporizador.
    t1.start();

    // Esperamos a que terminen dos ciclos (250 * 2).
    // 50 ms mas para asegurar que el temporizador
    // no se detuvo a medio ciclo.
    std::this_thread::sleep_for(Timer::Interval(550));

    // Detenemos el temporizador.
    t1.stop();

    // Verificamos que se corriero un solo ciclo.
    QCOMPARE(temporized, 1);
}

void Test_Timer::test_changes()
{
    /// Verificamos que las propiedades
    /// del temporizador no pueden ser
    /// modificadas a medio ciclo.

    /// Verificamos que no sea posible modificar
    /// el intervalo y la propiedad singleShot
    /// al estar corriendo el temporizador.
    // Establecemos las propiedades iniciales.
    bool temporized = false;

    Timer::Timeout iniTimeout
            = [&]() { temporized = true; };
    Timer::Interval iniInterval(250);
    bool iniSingle = true;

    Timer t1(iniTimeout, iniInterval, iniSingle);

    // Iniciamos el temporizador.
    t1.start();

    // Tratamos de cambiar las propiedades.
    t1.setTimeout([](){});
    t1.setInterval(Timer::Interval(10));
    t1.setSingleShot(false);

    // Verificamos que no fue posible el cambio
    // de las propiedades interval y singleShot.
    QCOMPARE(t1.interval(), iniInterval);
    QCOMPARE(t1.isSingleShot(), iniSingle);

    // Detenemos el temporizador.
    t1.stop();

    // Verificamos que no fue posible el cambio
    // de las propiedades interval y singleShot.
    // A pesar de tener el temporizador detenido.
    QCOMPARE(t1.interval(), iniInterval);
    QCOMPARE(t1.isSingleShot(), iniSingle);

    /// Verificamos que no sea posible modificar el
    /// timeout al estar corriendo el temporizador.
    // Establecemos que no a corrido ni un ciclo.
    temporized = false;

    // Iniciamos el temporizador.
    t1.start();

    // Esperamos a que termine.
    std::this_thread::sleep_for(Timer::Interval(255));

    // Detenemos el temporizador.
    t1.stop();

    // Verificamos que, a pesar de que se intento
    // cambiar el timeout por otro que no hace nada,
    // el viejo y unico timeout modifico a temporized.
    QCOMPARE(temporized, true);
}
